import {
	IParam,
	IMDCtrlAbility,
	IMDViewAbility,
	MDViewActionType,
	IMDViewControllerParams,
	SearchFormActionType,
	MDCtrlActionType,
	ISearchFormAbility,
	IMDViewModel,
	IMDViewStoreBase,
	IMDViewControllerBase,
	IViewActionResult,
} from '@/core/interface';
import { AuthUtil, deepCopy } from '@/core/utils';
import { DEViewController } from './de-view-controller';

export class MDViewControllerBase<
		T,
		S extends IMDViewStoreBase,
		A extends IMDViewAbility
	>
	extends DEViewController<T | MDViewActionType, S, A>
	implements IMDViewControllerBase<S, A>
{
	/**
	 * 视图模型
	 *
	 * @protected
	 * @type {IMDViewModel}
	 * @memberof MDViewControllerBase
	 */
	protected declare readonly model: IMDViewModel;

	/**
	 * 查询参数
	 *
	 * @protected
	 * @type {IParam}
	 * @memberof MDViewControllerBase
	 */
	protected queryParams: IParam = {};

	/**
	 * 是否抛出快速分组值
	 *
	 * @private
	 * @type {boolean}
	 * @memberof MDViewController
	 */
	protected isEmitQuickGroupValue = false;

	/**
	 * 处理视图初始化
	 *
	 * @protected
	 * @param {(IMDViewControllerParams<T | MDViewActionType, A>)} params
	 * @memberof MDViewControllerBase
	 */
	protected processViewInit(
		params: IMDViewControllerParams<T | MDViewActionType, A>
	) {
		super.processViewInit(params);
		Object.assign(this.store, { expandSearchForm: false });
	}

	/**
	 * 获取多数据部件能力（具体多数据视图实现）
	 *
	 * @protected
	 * @param {string} name
	 * @return {*}  {IMDCtrlAbility}
	 * @memberof MDViewControllerBase
	 */
	protected getMDCtrlAbility(): IMDCtrlAbility | undefined {
		throw new Error('Method is no');
	}

	/**
	 * 获取搜索表单能力
	 *
	 * @protected
	 * @return {*}  {(ISearchFormAbility | undefined)}
	 * @memberof MDViewControllerBase
	 */
	protected getSearchFormAbility(): ISearchFormAbility | undefined {
		const searchForm = this.model.ctrls.find(
			(ctrl: IParam) => ctrl.controlType === 'SEARCHFORM'
		);
		if (searchForm) {
			return this.getSubAbility<ISearchFormAbility>(searchForm.name);
		}
		return undefined;
	}

	/**
	 * 视图加载
	 *
	 * @param {IParam} [opts={}]
	 * @return {*}
	 * @memberof MDViewControllerBase
	 */
	public viewMounted(opts: IParam = {}) {
		super.viewMounted(opts);
		if (this.model.useDefaultLayout) {
			if (!this.isLoadDefault) {
				this.isLoadDefault = true;
				return;
			}
			if (
				this.model.enableQuickGroup &&
				this.model.quickGroupCodeList &&
				!this.isEmitQuickGroupValue
			) {
				return;
			}
			const searchForm = this.getSearchFormAbility();
			if (searchForm) {
				const tempViewParams = deepCopy(this.store.viewParams);
				searchForm.loadDraft(tempViewParams);
				return;
			}
			this.load();
		} else {
			this.initLayout().then(() => {
				this.load();
			});
		}
	}

	/**
	 * 处理部件行为
	 *
	 * @param {string} name
	 * @param {(MDCtrlActionType | SearchFormActionType)} action
	 * @param {IParam[]} data
	 * @memberof MDViewControllerBase
	 */
	public handleCtrlAction(
		name: string,
		action: MDCtrlActionType | SearchFormActionType,
		data: IParam[]
	): void {
		const mdCtrl = this.getMDCtrlAbility();
		if (mdCtrl && name === mdCtrl.name) {
			this.handleMDCtrlAction(action as MDCtrlActionType, data);
			return;
		}
		const searchForm = this.getSearchFormAbility();
		if (searchForm && name === searchForm.name) {
			this.handleSearchFormAction(action as SearchFormActionType, data);
			return;
		}
	}

	/**
	 * 处理搜索表单部件行为
	 *
	 * @param {SearchFormActionType} action
	 * @param {IParam[]} data
	 * @memberof MDViewControllerBase
	 */
	protected handleSearchFormAction(
		action: SearchFormActionType,
		data: IParam[]
	) {
		const mdCtrl = this.getMDCtrlAbility();
		if (mdCtrl) {
			if (action === 'load') {
				const tempViewParams = deepCopy(this.store.viewParams);
				mdCtrl.load(tempViewParams);
			}
			if (action === 'search') {
				this.store.expandSearchForm = false;
				const tempViewParams = deepCopy(this.store.viewParams);
				mdCtrl.load(tempViewParams, 'refresh');
			}
		}
	}

	/**
	 * 处理多数据部件行为
	 *
	 * @template T
	 * @param {(T | MDCtrlEventActionType)} action
	 * @param {IParam[]} data
	 * @memberof MDViewControllerBase
	 */
	protected handleMDCtrlAction<T>(
		action: T | MDCtrlActionType,
		data: IParam[]
	) {
		if (action === 'beforeLoad') {
			this.handleMDCtrlBeforeLoad(data);
		}
		if (action === 'load') {
			this.handleMDCtrlLoad(data);
		}
		if (action === 'selectionChange') {
			this.handleSelectionChange(data);
		}
		if (action === 'dataActive') {
			this.handleDataActive(data);
		}
	}

	/**
	 * 处理多数据部件加载之前
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof MDViewControllerBase
	 */
	protected handleMDCtrlBeforeLoad(data: IParam[]) {
		const param = data && data.length > 0 ? data[0] : {};
		const searchForm = this.getSearchFormAbility();
		if (searchForm) {
			Object.assign(param, searchForm.getData()[0]);
		}
		if (this.queryParams && Object.keys(this.queryParams).length > 0) {
			if (this.queryParams['quickGroupData']) {
				Object.assign(param, this.queryParams['quickGroupData']);
			}
			if (this.queryParams['query']) {
				Object.assign(param, { query: this.queryParams['query'] });
			}
		}
	}

	/**
	 * 处理多数据部件加载
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof MDViewControllerBase
	 */
	protected handleMDCtrlLoad(data: IParam[]) {
		AuthUtil.calcToolbarItemState(true, this.store.toolbarCtrls);
		this.calcToolbarItemAuthState(data[0]);
		this.emit('viewDataLoaded', data);
	}

	/**
	 * 处理选中
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @memberof MDViewControllerBase
	 */
	protected handleSelectionChange(data: IParam[]) {
		this.emit('viewDataChange', data);
		const state =
			data.length > 0 && !Object.is(data[0].srfkey, '') ? false : true;
		AuthUtil.calcToolbarItemState(state, this.store.toolbarCtrls);
		if (data && data.length > 0) {
			this.calcToolbarItemAuthState(data[0]);
		} else {
			this.calcToolbarItemAuthState({});
		}
	}

	/**
	 * 处理数据激活
	 *
	 * @protected
	 * @param {IParam[]} data
	 * @return {*}
	 * @memberof MDViewControllerBase
	 */
	protected handleDataActive(data: IParam[]) {
		if (!data || data.length === 0) {
			return;
		}
		const { context, viewParams } = this.store;
		this.openData(context, viewParams, data);
	}

	/**
	 * 快速分组值变化
	 *
	 * @param {IParam} item
	 * @memberof MDViewControllerBase
	 */
	public handleQuickGroupValueChange(item: IParam) {
		if (item) {
			this.queryParams.quickGroupData = item.data;
			const mdCtrl = this.getMDCtrlAbility();
			if (mdCtrl) {
				const tempViewParams = deepCopy(this.store.viewParams);
				mdCtrl.load({ ...tempViewParams, srfpagereset: true }, 'refresh');
			}
		}
		this.isEmitQuickGroupValue = true;
	}

	/**
	 * 搜索
	 *
	 * @param {string} searchValue
	 * @memberof MDViewControllerBase
	 */
	public search(searchValue: string) {
		this.queryParams.query = searchValue;
		const mdCtrl = this.getMDCtrlAbility();
		if (mdCtrl) {
			mdCtrl.load({ query: searchValue, srfpagereset: true });
		}
	}

	/**
	 * 切换过滤器
	 *
	 * @memberof MDViewControllerBase
	 */
	public toggleFilter(): void {
		this.store.expandSearchForm = !this.store.expandSearchForm;
	}

	/**
	 * 获取能力
	 *
	 * @return {*}  {A}
	 * @memberof MDViewControllerBase
	 */
	public getAbility(): A {
		return {
			...super.getAbility(),
			toggleFilter: this.toggleFilter.bind(this),
		};
	}

	/**
	 * 加载视图
	 *
	 * @param {IParam} [args]
	 * @return {*}  {Promise<IViewActionResult>}
	 * @memberof MDViewControllerBase
	 */
	public load(args?: IParam): Promise<IViewActionResult> {
		const searchForm = this.getSearchFormAbility();
		if (searchForm) {
			const tempViewParams = deepCopy(this.store.viewParams);
			return searchForm.loadDraft(tempViewParams);
		}
		const mdCtrl = this.getMDCtrlAbility();
		if (mdCtrl) {
			const tempViewParams = deepCopy(this.store.viewParams);
			return mdCtrl.load(Object.assign(tempViewParams, args));
		} else {
			return Promise.reject({
				ok: false,
				data: null,
				rowData: { status: 500 },
			});
		}
	}
}
